
interface IView {
    listNotificationInterests(): string[]
    handleNotification(notification: puremvc.INotification): void
}

interface IViewMediator {
    onLoad()
    onDestroy()
}

// export class Mediator {
//     public mediatorName: string;
//     public viewComponent: any;
//     static NAME: string;
// }
class ViewMediator<M> extends puremvc.Mediator implements IViewMediator{
    private static _mediator_id: number = 0
    constructor(viewComponent: View<M>) {
        ++ViewMediator._mediator_id;
        let mediatorName: string = "Mediator_" + ViewMediator._mediator_id
        super(mediatorName, viewComponent)
    }

    onLoad() {
        this.facade.registerMediator(this)
    }
    onDestroy() {
        this.facade.removeMediator(this.getMediatorName())
    }

    onRegister() {

    }
    onRemove() {

    }
    public listNotificationInterests(): string[] {
        let viewComponent = this.getViewComponent()
        return viewComponent.listNotificationInterests()
    }

    public handleNotification(notification: puremvc.INotification): void {
        let viewComponent = this.getViewComponent()
        return viewComponent.handleNotification(notification)
    }

}


export class Logic<T> extends puremvc.Mediator{
    private static _mediator_id:number = 0
    protected constructor(viewComponent:T = null){
        ++Logic._mediator_id
        let mediatorName:string="LG"+Logic._mediator_id
        super(mediatorName,viewComponent)
    }
}


const { ccclass, property } = cc._decorator
@ccclass
export class View<M> extends cc.Component implements IView {
    facade: puremvc.IFacade = null
    private mediator_: ViewMediator<M> = null
    protected _model: M = null
    public get model(): M { return this._model; }
    public set model(model: M) { this._model = model; }
    constructor() {
        super();
        this.facade = puremvc.Facade.getInstance();
        this.mediator_ = new ViewMediator<M>(this);
    }

    onLoad() {
        this.mediator_.onLoad()
    }
    onDestroy() {
        this.mediator_.onDestroy()
    }

    public listNotificationInterests(): string[] {
        return []
    }

    public handleNotification(notification: puremvc.INotification): void {

    }
}
export class Controller<M, V> extends Logic<V> {
    private _model: M = null
    public get model(): M { return this._model }
    public set model(model: M) { this._model = model }
    protected constructor(viewComponent: V = null) {
        super(viewComponent)
    }

}


export class Model extends puremvc.Proxy {
    constructor(proxyName: string, data: any = null) {
        super(proxyName, data)
        this.facade.registerProxy(this)
    }
}